package work.xiaohong.mina.test2.protocol;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolEncoderAdapter;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import work.xiaohong.mina.test2.message.GeneralMessage;
import work.xiaohong.mina.test2.message.PlcConstant;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author Kevin
 * @data 4/25/2022 1:07 PM
 * @description 自定义编码器
 **/
public class ProtocolEncoder extends ProtocolEncoderAdapter {
  @Override
  public void encode(IoSession ioSession, Object o, ProtocolEncoderOutput protocolEncoderOutput) throws Exception {

    GeneralMessage message = (GeneralMessage)o;

    // 分配buffer 并设置自动增长
    IoBuffer buffer = IoBuffer.allocate(PlcConstant.MaxLength).setAutoExpand(true);

    // 消息开始标识头
    buffer.put(new byte[]{PlcConstant.MessageHead});

    // 消息序列号
    buffer.put(message.getSequenceNumber().toString().getBytes(StandardCharsets.UTF_8));
    buffer.put(new byte[]{PlcConstant.MessageSeparator});

    // 消息是否需要响应 1的ASII是49 0是48
    buffer.put(message.getAcknowledgementRequired() ? new byte[]{ 49 }: new byte[]{ 48 });
    buffer.put(new byte[]{ PlcConstant.MessageSeparator });

    // 消息载体类型
    buffer.put(message.getPayloadType().getBytes(StandardCharsets.UTF_8));

    // 消息载体
    if (message.getPayload() != null){
      buffer.put(new byte[]{PlcConstant.MessageSeparator});
      String s = message.getPayload().toString();

      // 将实体类转换成协议字符串
      s = s.replaceAll("\":\"","=")
              .replaceAll("\":","=")
              .replaceAll("\",\"",";")
              .replaceAll("\\{\"","\\{")
              .replaceAll("\"}","}");
      s = s.substring(1,s.length()-1);

      buffer.put(s.getBytes(StandardCharsets.UTF_8));
    }

    // 消息结束标识符
    buffer.put(new byte[]{ PlcConstant.MessageEnd });

    // limit = position postiont = 0 将缓冲区的数据放入到流中，往往在发送数据之前调用
    buffer.flip();

    // 全部写出去
    protocolEncoderOutput.write(buffer);

    byte[] b = new byte [buffer.limit()];
    buffer.get(b);

    StringBuffer stringBuffer = new StringBuffer();

    for (int i = 0; i < b.length; i++) {

      stringBuffer.append((char) b [i]);

    }

    System.out.println(stringBuffer);

  }
}
